--- ldap.c.orig	Mon Jun 20 05:31:51 2005
+++ ldap.c	Fri May 19 00:29:52 2006
@@ -89,6 +89,7 @@
   char *tls_cipher_suite;
   char *tls_certfile;
   char *tls_keyfile;
+  char *uidbase;
   int debug;
 } ldap_conf;
 
@@ -548,6 +549,7 @@
     else MATCH_S("bindpw",  ldap_conf.bindpw)
     else MATCH_S("sudoers_base",    ldap_conf.base)
     else MATCH_I("sudoers_debug",   ldap_conf.debug)
+    else MATCH_S("uid_base_string",  ldap_conf.uidbase)
     else {
 
     /* The keyword was unrecognized.  Since this config file is shared
@@ -960,4 +962,193 @@
   if (ldap_conf.debug) printf("sudo_ldap_check(%d)=0x%02x\n",pwflag,ret);
 
   return ret ;
+}
+
+char *
+sudoget_ldappwd(username, password)
+char *username;
+char *password;
+{
+
+  LDAP *ld=NULL;
+
+  /* Used for searches */
+  LDAPMessage *result=NULL;
+  LDAPMessage *entry=NULL;
+  /* used to parse attributes */
+  char *filt;
+  /* temp/final return values */
+  int rc=0;
+  char *ret;
+  char *userdn;
+  char **p;
+  char *attrs [] =
+  { "sudoPassword",
+    NULL
+  };
+
+  /* macro to set option, error on failure plus consistent debugging */
+#define SET_OPT_CP(opt,optname,val) \
+  if (ldap_conf.val!=NULL) { \
+    if (ldap_conf.debug>1) fprintf(stderr, \
+           "ldap_set_option(LDAP_OPT_%s,\"%s\")\n",optname,ldap_conf.val); \
+    rc=ldap_set_option(ld,opt,ldap_conf.val); \
+    if(rc != LDAP_OPT_SUCCESS){ \
+      fprintf(stderr,"ldap_set_option(LDAP_OPT_%s,\"%s\")=%d: %s\n", \
+           optname, ldap_conf.val, rc, ldap_err2string(rc)); \
+      return NULL ; \
+    } \
+  } \
+
+  /* like above, but assumes val is in int */
+#define SET_OPTI_CP(opt,optname,val) \
+    if (ldap_conf.debug>1) fprintf(stderr, \
+           "ldap_set_option(LDAP_OPT_%s,0x%02x)\n",optname,ldap_conf.val); \
+    rc=ldap_set_option(ld,opt,&ldap_conf.val); \
+    if(rc != LDAP_OPT_SUCCESS){ \
+      fprintf(stderr,"ldap_set_option(LDAP_OPT_%s,0x%02x)=%d: %s\n", \
+           optname, ldap_conf.val, rc, ldap_err2string(rc)); \
+      return NULL ; \
+    } \
+
+  /* attempt to setup ssl options */
+#ifdef    LDAP_OPT_X_TLS_CACERTFILE
+  SET_OPT_CP(LDAP_OPT_X_TLS_CACERTFILE,   "X_TLS_CACERTFILE",   tls_cacertfile);
+#endif /* LDAP_OPT_X_TLS_CACERTFILE */
+
+#ifdef    LDAP_OPT_X_TLS_CACERTDIR
+  SET_OPT_CP(LDAP_OPT_X_TLS_CACERTDIR,    "X_TLS_CACERTDIR",    tls_cacertdir);
+#endif /* LDAP_OPT_X_TLS_CACERTDIR */
+
+#ifdef    LDAP_OPT_X_TLS_CERTFILE
+  SET_OPT_CP(LDAP_OPT_X_TLS_CERTFILE,     "X_TLS_CERTFILE",     tls_certfile);
+#endif /* LDAP_OPT_X_TLS_CERTFILE */
+
+#ifdef    LDAP_OPT_X_TLS_KEYFILE
+  SET_OPT_CP(LDAP_OPT_X_TLS_KEYFILE,      "X_TLS_KEYFILE",      tls_keyfile);
+#endif /* LDAP_OPT_X_TLS_KEYFILE */
+
+#ifdef    LDAP_OPT_X_TLS_CIPHER_SUITE
+  SET_OPT_CP(LDAP_OPT_X_TLS_CIPHER_SUITE, "X_TLS_CIPHER_SUITE", tls_cipher_suite);
+#endif /* LDAP_OPT_X_TLS_CIPHER_SUITE */
+
+#ifdef    LDAP_OPT_X_TLS_RANDOM_FILE
+  SET_OPT_CP(LDAP_OPT_X_TLS_RANDOM_FILE,  "X_TLS_RANDOM_FILE",  tls_random_file);
+#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */
+
+#ifdef    LDAP_OPT_X_TLS_REQUIRE_CERT
+  /* check the server certificate? */
+  if (ldap_conf.tls_checkpeer!=-1){
+   SET_OPTI_CP(LDAP_OPT_X_TLS_REQUIRE_CERT,"X_TLS_REQUIRE_CERT",tls_checkpeer);
+  }
+#endif /* LDAP_OPT_X_TLS_REQUIRE_CERT */
+
+  /* attempt connect */
+#ifdef HAVE_LDAP_INITIALIZE
+  if (ldap_conf.uri) {
+
+    if (ldap_conf.debug>1) fprintf(stderr,
+           "ldap_initialize(ld,%s)\n",ldap_conf.uri);
+
+    rc=ldap_initialize(&ld,ldap_conf.uri);
+    if(rc){
+      fprintf(stderr, "ldap_initialize()=%d : %s\n",
+           rc,ldap_err2string(rc));
+      return NULL;
+    }
+  } else
+#endif /* HAVE_LDAP_INITIALIZE */
+  if (ldap_conf.host) {
+
+    if (ldap_conf.debug>1) fprintf(stderr,
+           "ldap_init(%s,%d)\n",ldap_conf.host,ldap_conf.port);
+
+    ld=ldap_init(ldap_conf.host,ldap_conf.port);
+    if (!ld) {
+      fprintf(stderr, "ldap_init(): errno=%d : %s\n",
+                 errno, strerror(errno));
+      return NULL;
+    }
+  }
+
+#ifdef LDAP_OPT_PROTOCOL_VERSION
+
+  /* Set the LDAP Protocol version */
+  SET_OPTI_CP(LDAP_OPT_PROTOCOL_VERSION,"PROTOCOL_VERSION", version);
+
+#endif /* LDAP_OPT_PROTOCOL_VERSION */
+
+#ifdef HAVE_LDAP_START_TLS_S
+  /* Turn on TLS */
+  if (ldap_conf.ssl && !strcasecmp(ldap_conf.ssl, "start_tls")){
+    rc = ldap_start_tls_s(ld, NULL, NULL);
+    if (rc != LDAP_SUCCESS) {
+      fprintf(stderr, "ldap_start_tls_s(): %d: %s\n", rc, ldap_err2string(rc));
+      ldap_unbind(ld);
+      return NULL;
+    }
+
+    if (ldap_conf.debug) printf("ldap_start_tls_s() ok\n");
+  }
+#endif /* HAVE_LDAP_START_TLS_S */
+
+  /* Generate User's DN */
+  if(ldap_conf.uidbase == NULL || strstr (ldap_conf.uidbase, "%s") == NULL)
+  {
+    fprintf(stderr, "Please specify uid_base_string.\n");
+    exit(-1);
+  }
+  userdn = (char *) malloc ((strlen(ldap_conf.uidbase) + 
+	strlen(username) + 2) * sizeof(char) );
+  if(!userdn)
+  {
+    fprintf(stderr, "Cannot allocate memory!\n");
+    exit(-1);
+  }
+  sprintf(userdn, ldap_conf.uidbase, username);
+
+  /* Actually connect */
+  rc=ldap_simple_bind_s(ld,userdn,password);
+  if(rc){
+    fprintf(stderr,"ldap_simple_bind_s()=%d : %s\n",
+           rc, ldap_err2string(rc));
+    return NULL ;
+  }
+
+  if (ldap_conf.debug) printf("ldap_bind() ok\n");
+
+  /* get sudopassword */
+  rc=ldap_search_s(ld,userdn,LDAP_SCOPE_BASE, "uid=*",NULL,0,&result);
+
+  if (!rc && (entry=ldap_first_entry(ld,result))){
+    if (ldap_conf.debug) printf("found:%s\n",ldap_get_dn(ld,entry));
+  
+    p = ldap_get_values(ld, entry, "sudoPassword");
+    if(p && *p) /* sudopassword exists */
+    {
+      ret = (char *) malloc ((strlen(*p)+2) * sizeof(char));
+      if(!ret)
+      {
+	fprintf(stderr, "Cannot allocate memory!\n");
+	exit(-1);
+      } 
+      strcpy(ret, *p); 
+	
+      if(p) ldap_value_free(p);
+      /* if(entry) ldap_msgfree(entry); */
+      if(result) ldap_msgfree(result);
+      if(userdn) free(userdn);
+      return ret;
+    }
+  } 
+
+  if(p)
+    ldap_value_free(p);
+  if(entry)
+    ldap_msgfree(entry);
+  if(result)
+    ldap_msgfree(result);
+  if(userdn)
+    free(userdn);
+  return NULL;
 }
